home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr48 / sweep10.zip / SWEEP.DOC < prev    next >
Text File  |  1993-04-01  |  23KB  |  611 lines

  1.  
  2.  
  3.  
  4.                          Sweep Memory Management Library
  5.  
  6.                        Copyright (c) 1990-1991 Eric Tauck
  7.                                All Rights Reserved
  8.  
  9.                                    Eric Tauck
  10.                                1304 Deerpass Road
  11.                                 Marengo, IL 60152
  12.                                       U.S.A
  13.  
  14.                              Compuserve: 72457,1557
  15.                        Internet: 72457.1557@compuserve.com
  16.  
  17.         The Sweep Library is a library of routines for managing memory
  18.         and maintaining a heap.  The advantage of the Sweep Library over
  19.         the heap routines built into Turbo Pascal or Turbo C is that the
  20.         Sweep Library never suffers from memory fragmentation.  The Sweep
  21.         Library is ideal for applications that repeatedly allocate,
  22.         deallocate, and resize blocks of memory.
  23.  
  24.         The Sweep Library is available for Turbo C and Turbo Pascal.  The
  25.         Turbo C version should work with all versions of Turbo C and all
  26.         memory models except tiny.  The Turbo C version may also work
  27.         with other compilers that support standard LIB files and Pascal
  28.         calling conventions.  The Turbo Pascal version SWEEP5.TPU was
  29.         compiled with Turbo Pascal version 5.5 and should work with Turbo
  30.         Pascal versions 5.0 and 5.5, SWEEP6.TPU was compiled with Turbo
  31.         Pascal version 6.  You should rename the unit that matches your
  32.         version of Turbo Pascal to SWEEP.TPU.
  33.  
  34.         This library may be freely used and distributed.  The most recent
  35.         version of the Sweep Library, including the Turbo Assembler
  36.         source code, may be acquired on 5.25" or 3.5" disk by sending $20
  37.         to the address above.  The source code is for personal use only
  38.         and may not be distributed.  Refer to the end of this document
  39.         for a version history of the Sweep Library.
  40.  
  41.                              DISCLAIMER OF WARRANTY
  42.  
  43.         THIS SOFTWARE AND MANUAL ARE DISTRIBUTED "AS IS" AND WITHOUT
  44.         WARRANTIES AS TO PERFORMANCE OF MERCHANTABILITY OR ANY OTHER
  45.         WARRANTIES WHETHER EXPRESSED OR IMPLIED.  BECAUSE OF THE VARIOUS
  46.         HARDWARE AND SOFTWARE ENVIRONMENTS INTO WHICH THIS PROGRAM MAY BE
  47.         PUT, NO WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE IS OFFERED.
  48.  
  49.         GOOD DATA PROCESSING PROCEDURE DICTATES THAT ANY PROGRAM BE
  50.         THOROUGHLY TESTED WITH NON-CRITICAL DATA BEFORE RELYING ON IT.
  51.         THE USER MUST ASSUME THE ENTIRE RISK OF USING THE PROGRAM.  ANY
  52.         LIABILITY OF THE SELLER WILL BE LIMITED EXCLUSIVELY TO PRODUCT
  53.         REPLACEMENT OR REFUND OF PURCHASE PRICE.
  54.  
  55.  
  56.  
  57.                             Sweep Library Description
  58.                             -------------------------
  59.  
  60.         The necessary files for Turbo C are:
  61.  
  62.           SWEEP.LIB
  63.           SWEEP.H
  64.  
  65.         The Sweep Library routines are included in a Turbo C program by
  66.         using the #include statement and linking the library file with
  67.         your compiled program:
  68.  
  69.           #include "sweep.h"
  70.  
  71.         and compile as:
  72.  
  73.           tcc myprog sweep.lib
  74.  
  75.         The only file necessary for Turbo Pascal is:
  76.  
  77.           SWEEP.TPU
  78.  
  79.         The Sweep Library routines are included in a Turbo Pascal program
  80.         by using the USES statement:
  81.  
  82.           USES Sweep;
  83.  
  84.         A heap is created with the HeapInit or HeapInitBlk routines.
  85.         These routines require the address and size of a memory block in
  86.         which to create the heap.  The farcoreleft and farmalloc in Turbo
  87.         C provide ideal functions for allocating a block of memory for
  88.         the heap:
  89.  
  90.           /* Turbo C */
  91.  
  92.           #include "sweep.h"
  93.  
  94.           void far *base;          /* 'far' only for small/medium mdls */
  95.           unsigned long size;
  96.           size = farcoreleft();    /* bytes available */
  97.           base = farmalloc (size); /* allocate memory */
  98.           HeapInit (base, size);   /* create heap */
  99.  
  100.         Though you could use the MaxAvail and GetMem routines in Turbo
  101.         Pascal, you would be limited to a heap of 64K (because GetMem
  102.         will not allocate blocks larger than 64K).  This limitation can
  103.         be overcome by using three special Turbo Pascal routines provided
  104.         in the Sweep unit: DosAvail, DosAlloc, and DosFree.  These func-
  105.         tions allocate memory directly from the operating system rather
  106.         than the Turbo Pascal heap manager and are not restricted to 64K.
  107.         Since the Turbo Pascal heap manager usually takes all available
  108.         memory, you must use the $M directive to make some memory avail-
  109.         able:
  110.  
  111.  
  112.  
  113.           { Turbo Pascal }
  114.  
  115.           {$M 16384,0,0}    { tell TP not to use any extra mem. }
  116.           USES Sweep;       { remember: rename SWEEP5.TPU or SWEEP6.TPU }
  117.  
  118.           VAR
  119.             base: Pointer;
  120.             size: LongInt;
  121.           BEGIN
  122.             size := DosAvail;           { bytes available }
  123.             base := DosAlloc (size);    { allocate memory }
  124.             HeapInit (base, size);      { create heap }
  125.  
  126.         Once the heap has been created, you can allocate memory with
  127.         HeapAlloc and release memory with HeapFree.  HeapAlloc does not
  128.         return an address to the allocated memory, but rather a 16-bit
  129.         handle.  This handle type is called HeapHandle and is used by all
  130.         the heap management routines.  Memory blocks are accessed by
  131.         retrieving their address with HeapAddr and assigning this address
  132.         to a pointer:
  133.  
  134.           /* Turbo C */
  135.           /* create an array and zero all elements */
  136.           /* the fars are only needed for small or medium models */
  137.  
  138.           typedef int ArrayType [1000];
  139.  
  140.           HeapHandle MyArrayPtr;
  141.           ArrayType far *MyArray;
  142.           int i;
  143.  
  144.           MyArrayPtr = HeapAlloc (sizeof (ArrayType));
  145.           MyArray = (ArrayType far *) HeapAddr(MyArrayPtr);
  146.           for (i = 0; i < 1000; i++) (*MyArray)[i] = 0;
  147.  
  148.           { Turbo Pascal }
  149.           { create an array and zero all elements }
  150.  
  151.           TYPE
  152.             ArrayType = ARRAY [1..1000] OF Integer;
  153.           VAR
  154.             MyArrayPtr: HeapHandle;
  155.             MyArray: ^ArrayType;
  156.             i: Integer;
  157.           BEGIN
  158.             MyArrayPtr := HeapAlloc (SizeOf (ArrayType));
  159.             MyArray := HeapAddr (MyArrayPtr);
  160.  
  161.             FOR i := 1 TO 1000 DO MyArray^[i] := 0;
  162.  
  163.         You can use HeapResult or the value of the handle returned by
  164.         HeapAlloc and HeapResize to check for errors.  The error handle
  165.         in C is called SWEEP_NULL and in Pascal it's called SWEEP_NIL.
  166.         The value of SWEEP_NULL and SWEEP_NIL is zero, so in C you can
  167.  
  168.  
  169.  
  170.         use the value of the handle as a conditional expression:
  171.  
  172.           /* Turbo C */
  173.  
  174.           HeapHandle h;
  175.  
  176.           h = HeapAlloc (10);              /* allocate 10 bytes */
  177.           if (!h)                          /* if not allocated */
  178.             printf ("Allocation Error");   /* print error message */
  179.  
  180.         When a memory block is allocated or resized, the address of other
  181.         blocks may change.  This is a result of maintaining an unfrag-
  182.         mented heap.  The address of a block returned by HeapAddr is only
  183.         valid until the next time the heap is manipulated.
  184.  
  185.         A limitation of the Sweep Library heap routines is that there is
  186.         fixed number of blocks that can be allocated.  HeapInit sets the
  187.         maximum number of blocks to about 1/64 of the available memory
  188.         space.  The maximum number of blocks can be explicitly defined
  189.         with HeapInitBlk.
  190.  
  191.         The size of the heap can be changed with HeapShrink, HeapExpand,
  192.         and HeapReloc.  HeapShrink shrinks the heap by using less space
  193.         at the end of the heap.  HeapExpand enlarges the heap by using
  194.         more space at the end of the heap.  HeapReloc changes the base
  195.         address of an existing heap.  The following example creates a
  196.         10000 byte heap and then increases its size by 100 bytes:
  197.  
  198.           /* Turbo C */
  199.  
  200.           void far *base;
  201.           unsigned long size;
  202.           size = 10000;
  203.           base = farmalloc (size);
  204.           HeapInit (base, size);             /* create 10000 byte heap */
  205.  
  206.           base = farrealloc (base,size+100); /* increase by 100 bytes */
  207.           HeapReloc (base);                  /* relocate heap */
  208.           HeapExpand (100);                  /* expand heap */
  209.  
  210.         The HeapReloc is necessary in the example above because the C
  211.         function farrealloc may change address of the memory block being
  212.         reallocated.
  213.  
  214.         You can use the Sweep Library pointer manipulation routines to
  215.         access data structures greater than 64K in Turbo Pascal.  If you
  216.         calculate the 32 bit offset of an element within a large data
  217.         structure, you can add the offset to the base address with the
  218.         PointerAdd function, for instance:
  219.  
  220.           { Turbo Pascal }
  221.           { create array of 50000 integers and zero all elements }
  222.  
  223.           CONST
  224.             MyArrayDim = 50000;
  225.  
  226.  
  227.  
  228.             MyArrayElem = SizeOf (Integer);
  229.           VAR
  230.             MyArrayPtr: HeapHandle;
  231.             IntPtr: ^Integer;
  232.             i: Word;
  233.           BEGIN
  234.             MyArrayPtr := HeapAlloc (MyArrayDim * MyArrayElem);
  235.  
  236.             FOR i := 1 TO 1000 DO
  237.               BEGIN
  238.                 IntPtr := PointerAdd (HeapAddr (MyArrayPtr),
  239.                             LongInt(i - 1) * LongInt (MyArrayElem));
  240.                 IntPtr^ := 0;
  241.               END;
  242.  
  243.         You can use the same technique to access large data structures in
  244.         Turbo C.
  245.  
  246.  
  247.  
  248.                               Sweep Routine Summary
  249.                               ---------------------
  250.  
  251.         PointerNormal       normalize a pointer
  252.         PointerDenormal     denormalize a pointer
  253.         PointerAdd          add an offset to a pointer
  254.         PointerSub          subtract an offset from a pointer
  255.  
  256.         PointerValue        convert a pointer to a linear value
  257.         PointerDiff         calculate the difference between two pointers
  258.  
  259.         CopyBlock           copy a memory block
  260.         CopyForward         forward copy a memory block
  261.         CopyBackward        reverse copy a memory block
  262.  
  263.         HeapInit            initialize a heap
  264.         HeapInitBlk         initialize a heap with a block count
  265.  
  266.         HeapCurrent         return the current heap address
  267.         HeapSelect          switch to a new heap
  268.         HeapMemory          return the bytes available
  269.         HeapBlocks          return the blocks available
  270.  
  271.         HeapShrink          reduce the size of a heap
  272.         HeapExpand          increase the size of a heap
  273.         HeapReloc           relocate the heap
  274.  
  275.         HeapAlloc           allocate a memory block
  276.         HeapResize          resize a memory block
  277.         HeapFree            free a memory block
  278.         HeapSize            return the size of a memory block
  279.         HeapAddr            return the address of a memory block
  280.  
  281.         HeapResult          return the error code of the last operation
  282.  
  283.         DosAvail            return available system memory (Turbo Pascal)
  284.         DosAlloc            allocate system memory (Turbo Pascal)
  285.         DosFree             free system memory (Turbo Pascal)
  286.  
  287.  
  288.  
  289.                            Sweep Routine Descriptions
  290.                            --------------------------
  291.  
  292.         Though all the pointer values accepted and returned by the Turbo
  293.         C functions are listed as type 'far', all of the routines except
  294.         PointerDenormal (which always returns a far pointer) will also
  295.         work with huge pointers.  A 'far' modifier for pointer variables
  296.         is only necessary when using the small or medium memory models.
  297.         A 'huge' or 'near' modifier is never necessary.
  298.  
  299.         Many of the Turbo C routines return a value when the Turbo Pascal
  300.         equivalents don't.  Ignore any return value descriptions for
  301.         Turbo Pascal PROCEDURE types.
  302.  
  303.         CopyBackward
  304.  
  305.           - void far* CopyBackward (void far *d, void far *s,
  306.             unsigned long c)
  307.  
  308.           - PROCEDURE CopyBackward (d, s: Pointer; c: LongInt)
  309.  
  310.           Copy a contiguous block of memory.  The block may be greater
  311.           than 64K bytes.  The copy operation is started from the end of
  312.           the block, so an overlapping copy will only work if the desti-
  313.           nation is at a higher address than the source.  The destination
  314.           address is returned.  If the source and destination do not
  315.           overlap, this function has the same effect as CopyForward.
  316.  
  317.         CopyBlock
  318.  
  319.           - void far* CopyBlock (void far *d, void far *s,
  320.             unsigned long c)
  321.  
  322.           - PROCEDURE CopyBlock (d, s: Pointer; c: LongInt)
  323.  
  324.           Copy a contiguous block of memory.  The block may be greater
  325.           than 64K bytes.  The destination address is returned.  This
  326.           function works with all overlapping blocks (unlike CopyBackward
  327.           or CopyForward).
  328.  
  329.         CopyForward
  330.  
  331.           - void far * CopyForward (void far *d, void far *s,
  332.             unsigned long c)
  333.  
  334.           - PROCEDURE CopyForward (d, s: Pointer; c: LongInt)
  335.  
  336.           Copy a contiguous block of memory.  The block may be greater
  337.           than 64K bytes.  The copy operation is started from the begin-
  338.           ning of the block, so an overlapping copy will only work if the
  339.           destination is at a lower address than the source.  The desti-
  340.           nation address is returned.  If the source and destination do
  341.           not overlap, this function has the same effect as CopyBackward.
  342.  
  343.  
  344.  
  345.         DosAlloc
  346.  
  347.           - FUNCTION DosAlloc (s: LongInt): Pointer;
  348.  
  349.           Allocate system memory.  Memory must be made available using
  350.           the $M directive.  For instance {$M 16000,4000,4000} allocates
  351.           16000 bytes for the stack and 4000 bytes for the Turbo Pascal
  352.           heap.  All remaining system memory may be allocated by DosAl-
  353.           loc.  This function is only available in Turbo Pascal.
  354.  
  355.         DosAvail
  356.  
  357.           - FUNCTION DosAvail: LongInt;
  358.  
  359.           Return available system memory.  Use this function find the
  360.           largest block available for DosAlloc.  This function is only
  361.           available in Turbo Pascal.
  362.  
  363.         DosFree
  364.  
  365.           - PROCEDURE DosFree (p: Pointer);
  366.  
  367.           Free allocated system memory.  Use this function to release
  368.           memory allocated with DosAlloc.  This function is only avail-
  369.           able in Turbo Pascal.
  370.  
  371.         PointerAdd
  372.  
  373.           - void far * PointerAdd (void far *p, unsigned long o)
  374.  
  375.           - FUNCTION PointerAdd (p: Pointer; o: LongInt): Pointer;
  376.  
  377.           Add an offset to a far pointer.  The resulting address is
  378.           normalized.
  379.  
  380.         PointerDenormal
  381.  
  382.           - void far * PointerDenormal (void far *p)
  383.  
  384.           - FUNCTION PointerDenormal (p: Pointer): Pointer;
  385.  
  386.           Denormalize a far pointer.  As much of the segment of an ad-
  387.           dress as possible is transferred to the offset.  This function
  388.           does the opposite of PointerNormal.  The result is always a far
  389.           pointer, even when using the huge memory model.
  390.  
  391.         PointerDiff
  392.  
  393.           - unsigned long PointerDiff (void far *p1, void far *p2)
  394.  
  395.           - FUNCTION PointerDiff (p1, p2: Pointer): LongInt;
  396.  
  397.           Calculate the difference between two far pointers.  The result
  398.           is a standard 32 bit signed value (not a pointer).
  399.  
  400.  
  401.  
  402.         PointerNormal
  403.  
  404.           - void far * PointerNormal (void far *p)
  405.  
  406.           - FUNCTION PointerNormal (p: Pointer): Pointer;
  407.  
  408.           Normalize a far pointer.  As much of the offset of an address
  409.           as possible is transferred to the segment.  This function does
  410.           the opposite of PointerDenormal.
  411.  
  412.         PointerSub
  413.  
  414.           - void far * PointerSub (void far *p, unsigned long o)
  415.  
  416.           - FUNCTION PointerSub (p: Pointer; o: LongInt): Pointer;
  417.  
  418.           Subtract an offset from a far pointer.  The resulting address
  419.           is normalized.
  420.  
  421.         PointerValue
  422.  
  423.           - unsigned long PointerValue (void far *p)
  424.  
  425.           - FUNCTION PointerValue (p: Pointer): LongInt;
  426.  
  427.           Return the 32 bit linear value equivalent of a far pointer.
  428.           This function is used to calculate the difference between two
  429.           far pointers.
  430.  
  431.         HeapAddr
  432.  
  433.           - void far * HeapAddr (HeapHandle b)
  434.  
  435.           - FUNCTION HeapAddr (b: HeapHandle): Pointer;
  436.  
  437.           Return the address of a heap memory block.
  438.  
  439.         HeapAlloc
  440.  
  441.           - HeapHandle HeapAlloc (unsigned long s)
  442.  
  443.           - FUNCTION HeapAlloc (s: LongInt): HeapHandle;
  444.  
  445.           Allocate a memory block from the heap.  Return the block handle
  446.           or SWEEP_NULL (Turbo C) or SWEEP_NIL (Turbo Pascal) if error.
  447.           's' is the number of bytes to allocate.
  448.  
  449.         HeapBlocks
  450.  
  451.           - unsigned HeapBlocks (void)
  452.  
  453.           - FUNCTION HeapBlocks: Word;
  454.  
  455.           Return the number of available memory blocks in the heap.
  456.  
  457.  
  458.  
  459.         HeapCurrent
  460.  
  461.           - void far * HeapCurrent (void)
  462.  
  463.           - FUNCTION HeapCurrent: Pointer;
  464.  
  465.           Return the address of the current heap.
  466.  
  467.         HeapExpand
  468.  
  469.           - void far * HeapExpand (unsigned long s)
  470.  
  471.           - PROCEDURE HeapExpand (s: LongInt)
  472.  
  473.           Increase the size of the current heap.  The heap is expanded at
  474.           its end by 's' bytes.  The current heap address is returned.
  475.           Note: You are responsible for making sure that there is enough
  476.           available memory to perform this operation.
  477.  
  478.         HeapFree
  479.  
  480.           - void HeapFree (HeapHandle b)
  481.  
  482.           - PROCEDURE HeapFree (b: HeapHandle)
  483.  
  484.           Free a heap memory block.
  485.  
  486.         HeapInit
  487.  
  488.           - void far * HeapInit (void far *h, unsigned long s)
  489.  
  490.           - PROCEDURE HeapInit (h: Pointer; s: LongInt)
  491.  
  492.           Initialize a heap at the given address.  The minimum heap size
  493.           is 12 bytes.  The maximum number of blocks is calculated as the
  494.           heap size divided by 64 with a minimum of 32 and a maximum of
  495.           about 21800.  The newly initialized heap becomes the current
  496.           heap and the original heap address is returned.  The function
  497.           HeapInitBlk is identical except that the maximum number of
  498.           memory blocks is specified by the user rather than being calcu-
  499.           lated.  'h' is the base heap address and 's' is the number of
  500.           bytes allocated to the heap.
  501.  
  502.  
  503.  
  504.         HeapInitBlk
  505.  
  506.           - void far * HeapInitBlk (void far *h, unsigned long s,
  507.             unsigned b)
  508.  
  509.           - PROCEDURE HeapInitBlk (h: Pointer; s: LongInt; b: Word)
  510.  
  511.           Initialize a heap at the given address.  The minimum heap size
  512.           is 12 bytes. The maximum number of blocks may be adjusted down,
  513.           so use HeapBlocks to find the actual number initialized.  The
  514.           newly initialized heap becomes the current heap and the origi-
  515.           nal heap address is returned.  The function HeapInit is identi-
  516.           cal except that the maximum number of blocks is calculated
  517.           rather than being specified by the user.  'h' is the base heap
  518.           address, 's' is the number of bytes allocated to the heap, and
  519.           'b' is the number of blocks to assign to the heap.
  520.  
  521.         HeapMemory
  522.  
  523.           - unsigned long HeapMemory (void)
  524.  
  525.           - FUNCTION HeapMemory: LongInt;
  526.  
  527.           Return the total available bytes in the heap.
  528.  
  529.         HeapReloc
  530.  
  531.           - void far * HeapReloc (void far *h);
  532.  
  533.           - PROCEDURE HeapReloc (h: Pointer);
  534.  
  535.           Relocate the heap.  The current heap block addresses are
  536.           changed to reflect the new base address 'h'.  This function is
  537.           used if the heap is moved to a new location, though it doesn't
  538.           actually move the heap.  HeapReloc is useful when resizing the
  539.           memory block containing the heap or reading a saved heap into
  540.           memory.
  541.  
  542.         HeapResize
  543.  
  544.           - HeapHandle HeapResize (HeapHandle b, unsigned long s)
  545.  
  546.           - PROCEDURE HeapResize (b: HeapHandle; s: LongInt)
  547.  
  548.           Resize a heap memory block.  Returns the block handle (un-
  549.           changed) or SWEEP_NULL if error.
  550.  
  551.  
  552.  
  553.         HeapResult
  554.  
  555.           - int HeapResult (void)
  556.  
  557.           - FUNCTION HeapResult: Word;
  558.  
  559.           Return the error code of the last heap operation (or zero if no
  560.           error).  The error code is reset with each operation (including
  561.           this one).  An error code of 1 is out of memory and 2 is out of
  562.           memory blocks.  The symbolic constants SWEEP_NOERROR,
  563.           SWEEP_OUTOFBLOCKS, and SWEEP_OUTOFMEMORY have been defined to
  564.           check for these return values.
  565.  
  566.         HeapSelect
  567.  
  568.           -  void far * HeapSelect (void far *h)
  569.  
  570.           -  PROCEDURE HeapSelect (h: Pointer)
  571.  
  572.           Switch to a previously initialized heap.  Returns the current
  573.           heap address.
  574.  
  575.         HeapShrink
  576.  
  577.           - void far * HeapShrink (unsigned long s)
  578.  
  579.           - PROCEDURE HeapShrink (s: LongInt)
  580.  
  581.           Decrease the size of the heap.  The heap is adjusted at its end
  582.           by 's' bytes.  The current heap address is returned.  Note: the
  583.           heap MUST have at least 's' bytes free.
  584.  
  585.         HeapSize
  586.  
  587.           - unsigned long HeapSize (HeapHandle b)
  588.  
  589.           - FUNCTION HeapSize (b: HeapHandle): LongInt;
  590.  
  591.           Return the size of a heap memory block.
  592.  
  593.  
  594.  
  595.                                   Version History
  596.                                   ---------------
  597.  
  598.         Version   Description
  599.         -------   -----------
  600.  
  601.          1.00     Initial release.
  602.  
  603.          1.10     HeapReloc and CopyBlock functions added.  HeapShrink
  604.                   and HeapExpand now return the heap address (C versions
  605.                   only).  The value of SWEEP_NULL and SWEEP_NIL, returned
  606.                   by a HeapAlloc and HeapResize failure, is now zero.
  607.                   This allows the handle to be used in a C conditional
  608.                   statement (zero indicates failure, non-zero indicates
  609.                   success).  This library version is also slightly fast-
  610.                   er, primarily in memory copying.
  611.